package com.oos.zone.wechat.cp.config;

import com.oos.zone.wechat.cp.bean.MyWxCpXmlMessage;
import com.oos.zone.wechat.cp.service.handler.*;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.security.AnyTypePermission;
import me.chanjar.weixin.common.util.xml.XStreamInitializer;
import me.chanjar.weixin.cp.api.WxCpService;
import me.chanjar.weixin.cp.api.impl.WxCpServiceImpl;
import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage;
import me.chanjar.weixin.cp.config.WxCpConfigStorage;
import me.chanjar.weixin.cp.config.impl.WxCpDefaultConfigImpl;
import me.chanjar.weixin.cp.message.WxCpMessageRouter;
import me.chanjar.weixin.cp.util.xml.XStreamTransformer;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;

import static me.chanjar.weixin.common.api.WxConsts.XmlMsgType.EVENT;

/**
 * 功能描述：
 *
 * @author 拓金辉
 * @version 1.0
 * @date 2021-08-11 18:19:15
 */
@Configuration
public class WxCpServiceConfig implements InitializingBean {

    /**
     * 异步日志消息处理器
     */
    @Resource
    private WxCpAsyncLogMessageHandler wxCpAsyncLogMessageHandler;
    /**
     * 普通消息处理器
     */
    @Resource
    private WxCpStandardMessageHandler wxCpStandardMessageHandler;
    /**
     * 外部联系人事件处理器
     */
    @Resource
    private WxCpChangeExternalContactMessageHandler wxCpChangeExternalContactMessageHandler;
    /**
     * 企业客户标签事件处理器
     */
    @Resource
    private WxCpChangeExternalTagMessageHandler wxCpChangeExternalTagMessageHandler;
    /**
     * 客户群事件处理器
     */
    @Resource
    private WxCpChangeExternalChatMessageHandler wxCpChangeExternalChatMessageHandler;
    /**
     * 进入应用事件事件处理器
     */
    @Resource
    private WxCpEnterAgentMessageHandler wxCpEnterAgentMessageHandler;

    @Bean
    public WxCpConfigStorage wxCpConfigStorage() {
        String corpId = "wwe46f95710b3a4168";
        Integer agentId = 1000002;
        String corpSecret = "5FnJlfd6WQRV76MAUeZftA9ELC0O-vzrFIKRFBfoGXM";
        String aesKey = "qQXzQg7C7gNzkMIaQc9918HUPRRQo7XKcGc8NH9Mfob";

        WxCpDefaultConfigImpl newConfig = new WxCpDefaultConfigImpl();
        newConfig.setCorpId(corpId);
        newConfig.setAgentId(agentId);
        newConfig.setCorpSecret(corpSecret);
        String union = corpId + agentId + corpSecret;
        String token = UUID.nameUUIDFromBytes(union.getBytes(StandardCharsets.UTF_8)).toString().replace("-", "");
        newConfig.setToken(token);
        newConfig.setAesKey(aesKey);
        return newConfig;
    }

    @Bean
    public WxCpService wxCpService() {
        WxCpServiceImpl newService = new WxCpServiceImpl();
        newService.setWxCpConfigStorage(this.wxCpConfigStorage());
        return newService;
    }

    @Bean
    public WxCpMessageRouter wxCpMessageRouter() {
        final List<String> standMsgTypes = Arrays.asList("text", "image", "voice", "video", "shortvideo", "location", "link", "file");
        final WxCpMessageRouter newRouter = new WxCpMessageRouter(this.wxCpService());
        newRouter.rule().async(true).handler(wxCpAsyncLogMessageHandler).next();
        newRouter.rule().async(false).event(null).matcher(msg -> standMsgTypes.contains(msg.getMsgType())).handler(wxCpStandardMessageHandler).end();
        newRouter.rule().async(false).msgType(EVENT).event("change_external_contact").handler(wxCpChangeExternalContactMessageHandler).end();
        newRouter.rule().async(false).msgType(EVENT).event("change_external_tag").handler(wxCpChangeExternalTagMessageHandler).end();
        newRouter.rule().async(false).msgType(EVENT).event("change_external_chat").handler(wxCpChangeExternalChatMessageHandler).end();
        newRouter.rule().async(false).msgType(EVENT).event("enter_agent").handler(wxCpEnterAgentMessageHandler).end();
        return newRouter;
    }

    @Override
    public void afterPropertiesSet() {
        XStream xstream = XStreamInitializer.getInstance();
        xstream.addPermission(AnyTypePermission.ANY);
        xstream.processAnnotations(WxCpXmlMessage.class);
        xstream.processAnnotations(MyWxCpXmlMessage.class);
        xstream.processAnnotations(MyWxCpXmlMessage.ScanCodeInfo.class);
        xstream.processAnnotations(MyWxCpXmlMessage.SendPicsInfo.class);
        xstream.processAnnotations(MyWxCpXmlMessage.SendPicsInfo.Item.class);
        xstream.processAnnotations(MyWxCpXmlMessage.SendLocationInfo.class);
        xstream.processAnnotations(MyWxCpXmlMessage.BatchJob.class);
        XStreamTransformer.register(MyWxCpXmlMessage.class, xstream);
    }

}